package fr.capsuleaube.android.fragment;

import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.SearchView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import fr.capsuleaube.android.R;
import fr.capsuleaube.android.bean.Capsule;
import fr.capsuleaube.android.bean.Producteur;
import fr.capsuleaube.android.utils.Consts;
import fr.capsuleaube.android.utils.PageDownloader;

public class CapsulePhotoFragment extends Fragment implements AdapterView.OnItemClickListener {

    // Listener implémenté dans l'activité lorsqu'une photo est choisie
    private OnPhotoSelectedListener mOnPhotoSelectedListener;

    // Adapter associé à la Gridview contenant les producteurs
    private CapsulePhotoAdapter mCapsulePhotoAdapter;

    // Producteur sélectionné dans la ListView
    private Producteur mProducteur;

    // Ensemble des vue utilisée dans les différents scénarios d'utilisation
    private GridView mMainView;
    private View mLoadingView;
    private View mNetworkErrorView;

    // Utilisé pour afficher un message d'erreur à l'utilisateur
    // Positionné à vrai lorsque la requête HTTP a échouée
    private boolean mConnectionError = false;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        // Récupération du producteur sélectionné par l'utilisateur
        // et de la taille du fragment secondaire (seulement sur les tablettes), vaut 0 sinon
        Bundle args = getArguments();
        if (args != null) {
            mProducteur = args.getParcelable(Consts.PRODUCTEUR_BEAN);
        }

        View lView = inflater.inflate(R.layout.capsulephoto_fragment, container, false);

        // Instanciation de la Gridview
        mMainView = (GridView) lView.findViewById(R.id.capsule_photo_gridview);

        // Instanciation de la LoadingView et de l'ErrorView
        mLoadingView = lView.findViewById(R.id.capsule_photo_loading);
        mNetworkErrorView = lView.findViewById(R.id.capsule_photo_network_error);

        // Instantiation de l'adapter
        mCapsulePhotoAdapter = new CapsulePhotoAdapter(getActivity());
        mMainView.setAdapter(mCapsulePhotoAdapter);

        // Ajout de l'action lorsqu'on clique sur la un élements de la grille
        mMainView.setOnItemClickListener(this);

        if (mProducteur == null || mProducteur.getCapsuleArrayList().isEmpty()) {
            if (savedInstanceState != null && !savedInstanceState.getBoolean("mConnectionError") && savedInstanceState.getParcelable("mProducteur") != null) {
                // Lors d'un changement de configuration (rotation de l'écran par exemple)
                mProducteur = savedInstanceState.getParcelable("mProducteur");

                ArrayList<Capsule> capsuleArrayList = mProducteur.getCapsuleArrayList();
                for (Capsule c : capsuleArrayList) {
                    mCapsulePhotoAdapter.addListItems(c.getPhotoList());
                }

                mCapsulePhotoAdapter.notifyDataSetChanged();

                displayMainView();
            } else if (savedInstanceState != null && savedInstanceState.getBoolean("mConnectionError")) {
                // On recharge le fragment suite à une erreur réseau
                mProducteur = savedInstanceState.getParcelable("mProducteur");
                new PhotoListDownloader().execute(mProducteur);
            } else {
                // Téléchargement des photos ou chargement depuis le cache
                new PhotoListDownloader().execute(mProducteur);
            }

        } else {
            // Fragment créé ou restauré
            ArrayList<Capsule> capsuleArrayList = mProducteur.getCapsuleArrayList();
            for (Capsule c : capsuleArrayList) {
                mCapsulePhotoAdapter.addListItems(c.getPhotoList());
            }

            mCapsulePhotoAdapter.notifyDataSetChanged();
            displayMainView();
        }

        return lView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Permet l'instanciation de l'ActionBar
        setHasOptionsMenu(true);
        ActionBar lActionBar = ((ActionBarActivity) getActivity()).getSupportActionBar();
        lActionBar.setDisplayHomeAsUpEnabled(true);
        lActionBar.setTitle(mProducteur.getNom());
        lActionBar.setSubtitle(mProducteur.getVillage());
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // Inflate the menu items for use in the action bar
        menu.clear();
        inflater.inflate(R.menu.default_actionbar, menu);

        SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        if (searchItem != null) {
            SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
            searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
        }
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        // On récupére l'objet de la capsule sélectionnée
        List<Capsule> lCapsuleList = new ArrayList<Capsule>(mProducteur.getCapsuleArrayList());
        int lcapsuleId = lCapsuleList.get(i).getId();

        mOnPhotoSelectedListener.onPhotoSelected(mProducteur, lcapsuleId);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mOnPhotoSelectedListener = (OnPhotoSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement listener");
        }
    }

    private void displayMainView() {
        mNetworkErrorView.setVisibility(View.GONE);
        mLoadingView.setVisibility(View.GONE);
        mMainView.setVisibility(View.VISIBLE);
    }

    private void displayNetworkErrorView() {
        mLoadingView.setVisibility(View.GONE);
        mMainView.setVisibility(View.GONE);
        mNetworkErrorView.setVisibility(View.VISIBLE);
    }

    @Override
    public void onSaveInstanceState(Bundle pOutState) {
        super.onSaveInstanceState(pOutState);
        if (mProducteur != null && !mProducteur.getCapsuleArrayList().isEmpty()) {
            pOutState.putParcelable("mProducteur", mProducteur);
        }
        pOutState.putBoolean("mConnectionError", mConnectionError);
    }

    public interface OnPhotoSelectedListener {
        public void onPhotoSelected(Producteur pProducteur, int pCapsuleId);
    }

    public class PhotoListDownloader extends AsyncTask<Producteur, Void, Producteur> {

        @Override
        protected Producteur doInBackground(Producteur... pProducteurs) {

            Producteur lProducteur = pProducteurs[0];
            String lProducteurNom;
            String lProducteurVillage;

            if (lProducteur != null) {

                if (lProducteur.getNom().length() == 0) {
                    lProducteurNom = "%";
                    lProducteurVillage = "";
                } else {
                    lProducteurNom = lProducteur.getNom();
                    lProducteurVillage = lProducteur.getVillage();
                }

                PageDownloader lPageDL = new PageDownloader();
                String[] lReqParams = new String[]{"http://www.capsuleaube.fr/rechercheAndroidID.php", "GET", "detail=" + lProducteurNom, "village=" + lProducteurVillage};
                String lPageContent;

                try {
                    lPageContent = lPageDL.download(lReqParams);
                } catch (Exception e) {
                    mConnectionError = true;
                    return null;
                }

                String[] lCapsuleStringArray = lPageContent.split("\n");

                for (String s : lCapsuleStringArray) {

                    Capsule lCapsule = new Capsule();

                    String[] lSplitInfo = s.split("\\^");

                    if (lSplitInfo.length >= 0) {
                        if (lSplitInfo.length >= 2) {

                            if (lSplitInfo[1] != null && lSplitInfo[1].length() > 0) {
                                //Traitement pour les photos
                                String[] urlInfo = lSplitInfo[1].split(",");
                                for (String urlString : urlInfo) {
                                    try {
                                        URL url = new URL(urlString);
                                        lCapsule.addPhoto(url);
                                    } catch (MalformedURLException e) {
                                        // L'URL en erreur est ignorée et on continue
                                    }

                                }
                            }
                        }

                        if (lSplitInfo[0] != null && lSplitInfo[0].length() > 0) {
                            lCapsule.setId(Integer.parseInt(lSplitInfo[0]));
                        }

                        lProducteur.addCapsule(lCapsule);
                    }
                }
            }
            return lProducteur;
        }

        @Override
        protected void onPostExecute(Producteur pProducteur) {

            if (!mConnectionError) {
                mProducteur = pProducteur;
                ArrayList<Capsule> capsuleArrayList = mProducteur.getCapsuleArrayList();
                for (Capsule c : capsuleArrayList) {
                    mCapsulePhotoAdapter.addListItems(c.getPhotoList());
                }
                mCapsulePhotoAdapter.notifyDataSetChanged();

                displayMainView();
            } else {
                displayNetworkErrorView();
            }
        }
    }
}
